"""
Case Type   : DiskANN向量检索
Case Name   : 仅备机配置极致RTO备机读场景下，构建disakann索引场景，合理报错
Create At   : 2025-11-18
Owner       : sungang14
Description :
    1、备机打开极致RTO开关参数
    2、创建table插入数据
    3、主机创建diskann索引
    4、备机进行索引查询
    5、删除table
    6、还原极致RTO备机读开关
Expect      :
    1、开启成功
    2、创建成功，数据插入成功
    3、创建索引成功
    4、备机查询diskann索引失败
    5、删除操作成功
    6、还原参数成功
History     :
"""

import os
import time
import unittest

from testcase.utils.CommonSH import CommonSH
from testcase.utils.Constant import Constant
from testcase.utils.Logger import Logger

logger = Logger()
Primary_SH = CommonSH('PrimaryDbUser')


@unittest.skipIf(3 != Primary_SH.get_node_num(), '非1+2环境不执行')
class SlowSQLTestCase(unittest.TestCase):
    def setUp(self):
        logger.info(f'-----{os.path.basename(__file__)} start-----')
        self.constant = Constant()
        self.comsh = CommonSH('PrimaryDbUser')
        self.comsh_std1 = CommonSH('Standby1DbUser')
        self.comsh_std2 = CommonSH('Standby2DbUser')
        status = self.comsh.get_db_cluster_status('status')
        self.assertTrue(status)
        self.show_param_value1 = 'show hot_standby;'
        self.show_param_value2 = 'show recovery_parse_workers;'
        self.show_param_value3 = 'show recovery_redo_workers;'
        self.show_param_value4 = 'show exrto_standby_read_opt;'
        self.set_param_value1 = 'hot_standby=on'
        self.set_param_value2 = 'recovery_parse_workers=4'
        self.set_param_value3 = 'recovery_redo_workers=4'
        self.set_param_value4 = 'exrto_standby_read_opt=off'
        param_value1 = self.comsh.execut_db_sql(self.show_param_value1)
        logger.info(param_value1)
        param_value1 = param_value1.splitlines()[-2].strip()
        param_value2 = self.comsh.execut_db_sql(self.show_param_value2)
        logger.info(param_value2)
        param_value2 = param_value2.splitlines()[-2].strip()
        param_value3 = self.comsh.execut_db_sql(self.show_param_value3)
        logger.info(param_value3)
        param_value3 = param_value3.splitlines()[-2].strip()
        param_value4 = self.comsh.execut_db_sql(self.show_param_value4)
        logger.info(param_value4)
        param_value4 = param_value4.splitlines()[-2].strip()
        self.reset_param_value1 = f'hot_standby={param_value1}'
        self.reset_param_value2 = f'recovery_parse_workers={param_value2}'
        self.reset_param_value3 = f'recovery_redo_workers={param_value3}'
        self.reset_param_value4 = f'exrto_standby_read_opt={param_value4}'
        self.table_name = f't_func_diskann_index0046'
        self.index_name = f'idx_func_diskann_index0046'
        self.prepare_data_00 = f"drop table if exists {self.table_name};"
        self.prepare_data_01 = f'''
                                create table {self.table_name} (id bigserial primary key, val1 vector(5));
                                declare
                                 vector_dim int := 5;
                                 vector_value float[];
                                 record_num int := 1000;
                                 i int;
                                 j int;
                                begin
                                 for j in 1..record_num loop
                                 for i in 1..vector_dim loop
                                 vector_value[i] := random()*1000+1;
                                 end loop;
                                 insert into {self.table_name} (val1) values (vector_value);
                                 end loop;
                                end;
                                '''
        self.prepare_data_02 = f"drop index if exists {self.index_name};" \
                               f"alter table {self.table_name} set (parallel_workers=32);" \
                               f"create index {self.index_name} on {self.table_name} using diskann(val1 vector_l2_ops);"
        self.prepare_data_03 = f"set enable_seqscan=off;" \
                               f"set enable_indexscan=on;" \
                               f"select * from {self.table_name} order by val1 <-> '[1,2,3,4,5]' limit 2;"

    def test_slowsql(self):
        text = '--step1:备机打开极致RTO开关参数;expect:开启成功--'
        logger.info(text)
        set_cmd1 = self.comsh_std1.execute_gsguc('set',
                                                 self.constant.GSGUC_SUCCESS_MSG,
                                                 self.set_param_value1,
                                                 single=True)
        logger.info(set_cmd1)
        set_cmd2 = self.comsh_std1.execute_gsguc('set',
                                                 self.constant.GSGUC_SUCCESS_MSG,
                                                 self.set_param_value2,
                                                 single=True)
        logger.info(set_cmd2)
        set_cmd3 = self.comsh_std1.execute_gsguc('set',
                                                 self.constant.GSGUC_SUCCESS_MSG,
                                                 self.set_param_value3,
                                                 single=True)
        logger.info(set_cmd3)
        set_cmd4 = self.comsh_std1.execute_gsguc('set',
                                                 self.constant.GSGUC_SUCCESS_MSG,
                                                 self.set_param_value4,
                                                 single=True)
        logger.info(set_cmd4)
        set_cmd1 = self.comsh_std2.execute_gsguc('set',
                                                 self.constant.GSGUC_SUCCESS_MSG,
                                                 self.set_param_value1,
                                                 single=True)
        logger.info(set_cmd1)
        set_cmd2 = self.comsh_std2.execute_gsguc('set',
                                                 self.constant.GSGUC_SUCCESS_MSG,
                                                 self.set_param_value2,
                                                 single=True)
        logger.info(set_cmd2)
        set_cmd3 = self.comsh_std2.execute_gsguc('set',
                                                 self.constant.GSGUC_SUCCESS_MSG,
                                                 self.set_param_value3,
                                                 single=True)
        logger.info(set_cmd3)
        set_cmd4 = self.comsh_std2.execute_gsguc('set',
                                                 self.constant.GSGUC_SUCCESS_MSG,
                                                 self.set_param_value4,
                                                 single=True)
        logger.info(set_cmd4)
        self.restart_flag = self.comsh.restart_db_cluster()
        self.assertTrue(self.restart_flag)

        text = '--step2:创建table插入数据;expect:创建成功，数据插入成功--'
        logger.info(text)
        data_cmd = self.comsh.execut_db_sql(self.prepare_data_00)
        logger.info(data_cmd)
        self.assertIn(self.constant.TABLE_DROP_SUCCESS, data_cmd, '执行失败' + text)
        data_cmd = self.comsh.execut_db_sql(self.prepare_data_01)
        logger.info(data_cmd)
        self.assertIn(self.constant.TABLE_CREATE_SUCCESS, data_cmd, '执行失败' + text)
        self.assertIn(f'ANONYMOUS BLOCK EXECUTE', data_cmd, '执行失败' + text)

        text = '--step3:主机创建diskann索引;expect:创建成功--'
        logger.info(text)
        data_cmd = self.comsh.execut_db_sql(self.prepare_data_02)
        logger.info(data_cmd)
        self.assertIn(self.constant.DROP_INDEX_SUCCESS_MSG, data_cmd, '执行失败' + text)
        self.assertIn(self.constant.ALTER_TABLE_MSG, data_cmd, '执行失败' + text)
        self.assertIn(self.constant.CREATE_INDEX_SUCCESS, data_cmd, '执行失败' + text)

        text = '--step4:备机进行索引查询;expect:备机查询diskann索引失败--'
        logger.info(text)
        data_cmd = self.comsh_std1.execut_db_sql(self.prepare_data_03)
        logger.info(data_cmd)
        self.assertIn(f"NOTICE:  Ann Index does not support extreme RTO", data_cmd, '执行失败' + text)

    def tearDown(self):
        text = '--step4:清理环境，恢复默认值;expect:成功--'
        logger.info(text)
        data_cmd = self.comsh.execut_db_sql(self.prepare_data_00)
        logger.info(data_cmd)
        self.assertIn(self.constant.TABLE_DROP_SUCCESS, data_cmd, '执行失败' + text)
        set_cmd1 = self.comsh_std1.execute_gsguc('set',
                                                 self.constant.GSGUC_SUCCESS_MSG,
                                                 self.reset_param_value1,
                                                 single=True)
        logger.info(set_cmd1)
        set_cmd2 = self.comsh_std1.execute_gsguc('set',
                                                 self.constant.GSGUC_SUCCESS_MSG,
                                                 self.reset_param_value2,
                                                 single=True)
        logger.info(set_cmd2)
        set_cmd3 = self.comsh_std1.execute_gsguc('set',
                                                 self.constant.GSGUC_SUCCESS_MSG,
                                                 self.reset_param_value3,
                                                 single=True)
        logger.info(set_cmd3)
        set_cmd4 = self.comsh_std1.execute_gsguc('set',
                                                 self.constant.GSGUC_SUCCESS_MSG,
                                                 self.reset_param_value4,
                                                 single=True)
        logger.info(set_cmd4)
        logger.info(data_cmd)
        self.assertIn(self.constant.TABLE_DROP_SUCCESS, data_cmd, '执行失败' + text)
        set_cmd1 = self.comsh_std2.execute_gsguc('set',
                                                 self.constant.GSGUC_SUCCESS_MSG,
                                                 self.reset_param_value1,
                                                 single=True)
        logger.info(set_cmd1)
        set_cmd2 = self.comsh_std2.execute_gsguc('set',
                                                 self.constant.GSGUC_SUCCESS_MSG,
                                                 self.reset_param_value2,
                                                 single=True)
        logger.info(set_cmd2)
        set_cmd3 = self.comsh_std2.execute_gsguc('set',
                                                 self.constant.GSGUC_SUCCESS_MSG,
                                                 self.reset_param_value3,
                                                 single=True)
        logger.info(set_cmd3)
        set_cmd4 = self.comsh_std2.execute_gsguc('set',
                                                 self.constant.GSGUC_SUCCESS_MSG,
                                                 self.reset_param_value4,
                                                 single=True)
        logger.info(set_cmd4)
        self.restart_flag = self.comsh.restart_db_cluster()
        self.assertTrue(self.restart_flag)
        logger.info(f'-----{os.path.basename(__file__)} end-----')
